﻿using System.Windows;
using DaphneProfi.ViewModel;
using GameEngine;
using Daphne.Presenters;
using System.Reflection;
using GalaSoft.MvvmLight.Ioc;
using DaphneControls.ViewModel;
using GalaSoft.MvvmLight.Messaging;
using DaphneProfiBase;
using Tomers.WPF.Localization;
using System;
using DaphneForms.ViewModel;
using AvalonDock.Layout;
using DaphneControls;
using System.Collections;
using System.Linq.Expressions;
using System.Linq;



namespace DaphneProfi
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {


        /// <summary>
        /// Initializes a new instance of the MainWindow class.
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
            Closing += (s, e) => ViewModelLocator.Cleanup();
            Closing += (s, e) => DaphneControlsLocator.Cleanup();

            this.Loaded += MainWindow_Loaded;

            // register message for setting language
            Messenger.Default.Register<NotificationMessage<eLanguage>>(this, (nm) =>
                {
                    if (nm.Notification == Notify.SettingLanguage)
                        RefreshPanelHeaders();
                });

            // register message for showing the panel
            Messenger.Default.Register<NotificationMessage<ePanelType>>(this, (nm) =>
                {
                    if (nm.Notification == Notify.ShowPanel)
                    {
                        switch (nm.Content)
                        {
                            case ePanelType.Game:
                                panelGame.Show();
                                panelGame.IsActive = true;
                                break;
                            case ePanelType.Tablebases:
                                panelTablebases.Show();
                                panelTablebases.IsActive = true;
                                break;
                            case ePanelType.GameLibrary:
                                panelGameList.Show();
                                panelGameList.IsActive = true;
                                break;
                            case ePanelType.EngineOutput:
                                panelEngineOutput.Show();
                                panelEngineOutput.IsActive = true;
                                break;
                            case ePanelType.MatchOutput:
                                panelMatchOutput.Show();
                                panelMatchOutput.IsActive = true;
                                break;
                            case ePanelType.Editor:
                                panelEditor.Show();
                                panelEditor.IsActive = true;
                                break;
                            default:
                                throw new ApplicationException("Unknown panel type");
                        }
                    }
                });

            // register message to start the new game
            Messenger.Default.Register<NotificationMessage<NewGameFormSettings>>(this, (nm) =>
                {
                    if (nm.Notification == Notify.NewGame && nm.Sender == this.DataContext)
                    {
                        StartNewGame(nm.Content);
                    }
                });

            // register message for opening game from game library
            Messenger.Default.Register<NotificationMessage<GameManager>>(this, (nm) =>
                {
                    if (nm.Notification == Notify.OpenGameFromGameList)
                    {
                        OpenGame(nm.Content);
                    }
                });

            // register message for starting the engine match
            Messenger.Default.Register<NotificationMessage<RunMatchSettings>>(this, (nm) =>
                {
                    if (nm.Notification == Notify.RunEngineMatch)
                    {
                        RunEngineMatch(nm.Content);
                    }
                });

            this.Closing += MainWindow_Closing;

            // event for monitoring active checkersboards
            uxDockingManager.ActiveContentChanged += uxDockingManager_ActiveContentChanged;
            uxDockingManager.DocumentClosed += uxDockingManager_DocumentClosed;
        }

        /// <summary>
        /// General method for closing the document
        /// </summary>
        /// <param name="cb"></param>
        private void CloseDocument(CheckersBoard cb)
        {
            Messenger.Default.Send<NotificationMessage<object>>(
                new NotificationMessage<object>(cb.DataContext, Notify.CloseCheckersBoard));               
        }


        /// <summary>
        /// Event handler for monitoring active content - for monitoring selected checkers board
        /// </summary>
        void uxDockingManager_ActiveContentChanged(object sender, EventArgs e)
        {
            object objContent = uxDockingManager.ActiveContent;

            // check if active content is checkers board
            if (objContent is CheckersBoard)
            {
                CheckersBoard checkersBoard = objContent as CheckersBoard;
                CheckersBoardVM vm = checkersBoard.DataContext as CheckersBoardVM;

                // send message about active checkers board
                Messenger.Default.Send<NotificationMessage<CheckersBoardVM>>(
                    new NotificationMessage<CheckersBoardVM>(vm, Notify.SetIsActiveBoard));
            }
        }

        /// <summary>
        /// Handle closing the documents
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void uxDockingManager_DocumentClosed(object sender, AvalonDock.DocumentClosedEventArgs e)
        {
            // check, if checkersboard is closed
            if (e.Document.Content is CheckersBoard)
            {
                CheckersBoard cb = e.Document.Content as CheckersBoard;
                CloseDocument(cb);
            }           
        }

        /// <summary>
        /// Handle when the main window is closing
        /// </summary>
        void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // Close all documents
            var firstDocumentPane = uxDockingManager.Layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
            if (firstDocumentPane != null)
            {
                while (firstDocumentPane.Children.Count > 0)
                {
                    var objDoc = firstDocumentPane.Children[0];
                    if (objDoc is LayoutDocument)
                    {
                        LayoutDocument doc = objDoc as LayoutDocument;
                        if (doc.Content is CheckersBoard)
                        {
                            CheckersBoard cb = doc.Content as CheckersBoard;
                            CloseDocument(cb);
                            doc.Close();
                        }
                    }
                }
            }
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            RefreshPanelHeaders();
        }

        /// <summary>
        /// Starts the new game
        /// </summary>
        private void StartNewGame(NewGameFormSettings settings)
        {
            var firstDocumentPane = uxDockingManager.Layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
            if (firstDocumentPane != null)
            {
                // create layout document
                LayoutDocument doc = new LayoutDocument();
                doc.Title = LanguageContext.Instance.Dictionary.Translate<string>("panelCheckersBoard", "Title");

                // create checkers board
                CheckersBoardVM vm = new CheckersBoardVM();
                CheckersBoard board = new CheckersBoard();
                board.DataContext = vm;
                doc.Content = board;
                vm.Initialize(settings);

                firstDocumentPane.Children.Add(doc);
                doc.IsActive = true;
            }
        }

        /// <summary>
        /// Opens existing game
        /// </summary>
        private void OpenGame(GameManager gameManager)
        {
            var firstDocumentPane = uxDockingManager.Layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
            if (firstDocumentPane != null)
            {
                // create layout document
                LayoutDocument doc = new LayoutDocument();
                doc.Title = LanguageContext.Instance.Dictionary.Translate<string>("panelCheckersBoard", "Title");

                // create checkers board
                CheckersBoardVM vm = new CheckersBoardVM();
                CheckersBoard board = new CheckersBoard();
                board.DataContext = vm;
                doc.Content = board;
                vm.Initialize(gameManager);

                firstDocumentPane.Children.Add(doc);
                doc.IsActive = true;
            }
        }

        /// <summary>
        /// Starts the engine match
        /// </summary>
        /// <param name="settings"></param>
        private void RunEngineMatch(RunMatchSettings settings)
        {
            var firstDocumentPane = uxDockingManager.Layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
            if (firstDocumentPane != null)
            {
                // create layout document
                LayoutDocument doc = new LayoutDocument();
                doc.Title = LanguageContext.Instance.Dictionary.Translate<string>("panelCheckersBoard", "Title");

                // create checkers board
                CheckersBoardVM vm = new CheckersBoardVM();
                CheckersBoard board = new CheckersBoard();
                board.DataContext = vm;
                doc.Content = board;
                vm.Initialize(settings);

                // show match output panel
                panelMatchOutput.Show();
                panelMatchOutput.IsActive = true;

                firstDocumentPane.Children.Add(doc);
                doc.IsActive = true;
            }

        }


        /// <summary>
        /// Sets the header titles of dock panels
        /// </summary>
        private void RefreshPanelHeaders()
        {
            // set the UI
            panelGame.Title = LanguageContext.Instance.Dictionary.Translate<string>("panelGame", "Title");
            panelTablebases.Title = LanguageContext.Instance.Dictionary.Translate<string>("panelTablebases", "Title");
            panelGameList.Title = LanguageContext.Instance.Dictionary.Translate<string>("panelGameList", "Title");
            panelEngineOutput.Title = LanguageContext.Instance.Dictionary.Translate<string>("panelEngineOutput", "Title");
            panelMatchOutput.Title = LanguageContext.Instance.Dictionary.Translate<string>("panelMatchOutput", "Title");
            panelEditor.Title = LanguageContext.Instance.Dictionary.Translate<string>("panelEditor", "Title");
        }
    }
}